package com.ruoyi.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.project.domain.entity.ProjectAccounting;
import com.ruoyi.project.domain.entity.ProjectCompany;
import com.ruoyi.project.domain.entity.ProjectGoods;
import com.ruoyi.project.domain.entity.ProjectStore;
import com.ruoyi.project.domain.query.ProjectGoodsQuery;
import com.ruoyi.project.domain.query.ProjectStoreQuery;
import com.ruoyi.project.mapper.ProjectCompanyMapper;
import com.ruoyi.project.mapper.ProjectGoodsMapper;
import com.ruoyi.project.mapper.ProjectStoreMapper;
import com.ruoyi.project.service.IProjectCompanyService;
import com.ruoyi.project.service.IProjectGoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Service
public class ProjectGoodsServiceImpl extends ServiceImpl<ProjectGoodsMapper, ProjectGoods> implements IProjectGoodsService {
    @Resource
    private ProjectGoodsMapper projectGoodsMapper;

    @Resource
    private ProjectStoreMapper projectStoreMapper;

    @Autowired
    private RedisCache redisCache;

    @Override
    @Async("taskExecutor") // 指定使用的线程池
    public void syncData(List<ProjectGoods> list) {
        this.saveOrUpdateBatch(list); //更新或添加
    }

    @Override
    public List<ProjectGoods> getList(ProjectGoodsQuery query) {
        LambdaQueryWrapper<ProjectGoods> wrapper = new QueryWrapper<ProjectGoods>().lambda()
                .eq(query.getModal() != null, ProjectGoods::getModal, query.getModal());
        return this.list(wrapper);
    }

    @Override
    public TableDataInfo getListPage(ProjectGoodsQuery query) {


        String keys = buildKeys(query);


        Object cacheObject = redisCache.getCacheObject(keys + "goodListPage");
        if (cacheObject != null) {
            return (TableDataInfo) cacheObject;
        }

        if (query.getStoreDate() != null && query.getStoreDate().length > 0) {
            query.setStartDate(query.getStoreDate()[0]);
            query.setEndDate(query.getStoreDate()[1]);
            ProjectStoreQuery storeQuery = new ProjectStoreQuery();
            storeQuery.setStartDate(query.getStartDate());
            storeQuery.setEndDate(query.getEndDate());
            List<ProjectStore> storeList = projectStoreMapper.selectStorePage(storeQuery);
            List<String> goodsIdList = storeList.stream()
                    .map(ProjectStore::getGoodsId)
                    .collect(Collectors.toList());
            query.setIdList(goodsIdList);

        }


        LambdaQueryWrapper<ProjectGoods> wrapper = new QueryWrapper<ProjectGoods>().lambda();
        if (StringUtils.isNotEmpty(query.getModal())) {
            wrapper.like(ProjectGoods::getModal, query.getModal().trim());
        }
        wrapper.like(query.getFullName() != null, ProjectGoods::getFullName, query.getFullName());
        wrapper.in((query.getIdList() != null && query.getIdList().size() > 0), ProjectGoods::getId, query.getIdList());
        wrapper.orderByAsc(ProjectGoods::getFullName);

        Page<Object> page = PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<ProjectGoods> goodsList = this.list(wrapper);


        for (ProjectGoods projectGoods : goodsList) {
            if (projectGoods.getId() == null) {
                continue; // 如果没有 ID，跳过
            }


            Integer saleCount = projectStoreMapper.selectSaleCount(projectGoods.getId());
            Integer storeCount = projectStoreMapper.selectStoreCount(projectGoods.getId());
            storeCount = storeCount == null ? 0 : storeCount;
            saleCount = saleCount == null ? 0 : saleCount;
            //库存剩余
            Integer remaining = saleCount + storeCount;
            projectGoods.setRemaining(remaining);

            // 查询历史采购价格
            LambdaQueryWrapper<ProjectStore> storeWrapper = new LambdaQueryWrapper<>();
            storeWrapper.eq(ProjectStore::getGoodsId, projectGoods.getId());
            storeWrapper.orderByDesc(ProjectStore::getStorageDate);
            List<ProjectStore> storeList = new ArrayList<>();
            if (query.getIdList() != null && query.getIdList().size() > 0) {
                storeList = projectStoreMapper.selectStoreByGoodsId(projectGoods.getId(), query.getStartDate(), query.getEndDate());
            } else {
                storeList = projectStoreMapper.selectList(storeWrapper);
            }

            if (storeList == null || storeList.size() == 0) {
                continue;
            }


            // 将每条记录转换为前端可展示的文本列表
            Integer count = 0;
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 定义格式
            List<Map<String, Object>> historyCostList = new ArrayList<>();
            BigDecimal totalCost = BigDecimal.ZERO;
            int size = storeList.size();
            BigDecimal minPrice = null; // 用于记录大于0的最低价
            for (int i = 0; i < storeList.size(); i++) {
                count++;
                ProjectStore store = storeList.get(i);
                String dateStr = store.getStorageDate() != null ? sdf.format(store.getStorageDate()) : "未知";
                Map<String, Object> item = new HashMap<>();
                item.put("price", store.getPrice());
                item.put("date", dateStr);
                item.put("index", size - i); // 第几批
                item.put("count", store.getAmount());
                historyCostList.add(item);
                totalCost = totalCost.add(store.getPrice());

                // 关键：判断 price 是否 > 0，并更新最小值
                BigDecimal price = store.getPrice();
                if (price != null && price.compareTo(BigDecimal.ZERO) > 0) { // price > 0
                    if (minPrice == null || price.compareTo(minPrice) < 0) {
                        minPrice = price;
                    }
                }
            }
            BigDecimal avgCost = totalCost.divide(BigDecimal.valueOf(count), 2, BigDecimal.ROUND_HALF_UP);
            projectGoods.setMinPrice(minPrice);

            // 设置为 List<String>，而不是单个字符串
            projectGoods.setHistoryCostList(historyCostList); // 注意：字段名改为 historyCostList
            projectGoods.setAvgCost(avgCost);
        }


        redisCache.redisTemplate.opsForValue().set(keys + "goodListPage",new  TableDataInfo(goodsList, page.getTotal()),7, TimeUnit.DAYS);



        return new TableDataInfo(goodsList, page.getTotal());

    }


    public String buildKeys(ProjectGoodsQuery query) {
        //构建查询参数 key
        String keys = "";
        int pageSize = query.getPageSize();
        int pageNum = query.getPageNum();

        keys = keys + pageSize + pageNum;

        String modal = query.getModal();
        String fullName = query.getFullName();
        LocalDate[] storeDate = query.getStoreDate();
        if (StringUtils.isNotEmpty(modal)){
            keys = keys + modal;
        }

        if (StringUtils.isNotEmpty(fullName)){
            keys = keys + fullName;
        }

        if (storeDate != null && storeDate.length > 0) {
            for (int i = 0; i < storeDate.length; i++) {
                keys = keys + storeDate[i].toString();
            }

        }

        return keys;
    }

    @Override
    public Boolean addInfo(ProjectGoods project) {
        return this.save(project);
    }

    @Override
    public Boolean updateInfo(ProjectGoods project) {
        return this.updateInfo(project);
    }

    @Override
    public Boolean deleteInfo(String id) {
        return this.removeById(id);
    }

    @Override
    public ProjectGoods getInfoById(String id) {
        return this.getById(id);
    }

}
